/**
    ATClab - scriptable Air Traffic Control simulations.
    Copyright (C) 2010 openatclab@gmail.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef __ATC_PARAM_HDR__
#define __ATC_PARAM_HDR__

#include "atc.h"
#include "canvas_types.h"
#include "canvas_action.h"
#include <string>

class QColor;
class QKeySequence;


namespace atc{

	enum ControlState;
	//enum CanvasItem::TOOL;

	class Score;

	/*!
	 * 
	enum ToolType {
			SCALE_TOOL,
			ALTITUDE_TOOL,
			AIRSPEED_TOOL
		};
	 */

	enum AircraftAcceptanceType
	{
		ACCEPTANCE_MANUAL,
		ACCEPTANCE_AUTOMATIC
	};

	/*!
	 * 
	 */
	struct ToolParams {
		ToolParams() : build(0) {};
		ToolParams( CanvasEventHandlerBuilder *b ) : build(b) {};

		CanvasEventHandlerBuilder *build;
	};

	struct InfoDisplayDetails
	{
		InfoDisplayDetails()
			: m_label(""), 
			  m_globalRef(""),
			  m_text("")
		{
		}

		std::string m_label;
		std::string m_globalRef;
		std::string m_text;
	};

	/*!
	 * \class atc::Param
	 * \brief Interface (mutator) for setting up experimental parameters.
	 */
	class Param
	{
	public:

		/*!
		 * Set the update (advance) rate in milliseconds.
		 *
		 * \param rate generally values >1000ms should be used (untested).
		 */
		virtual void set_update_rate(unsigned int rate) = 0;

		// Set if all aircrafts have to be manually accepted
		virtual void SetAircraftAcceptanceType(AircraftAcceptanceType a_type) = 0;

		/*!
		 * Set the update (advance) multiplier.
		 *
		 * The multiplier is used to run the experiment in 'quick-time'. The
		 * experiment clock will be sped up by the multipier so that events
		 * will happen at consistent times no matter what value is set.
		 *
		 * \param multiplier >0 (untested; upper limit determined by hardware).
		 */
		virtual void set_update_multiplier( float ) = 0;

		/* 
			Set what happens when a user declares a conflict. They can either
			a) Have score updates
			b) Have audio feedback
			c) The aircraft for the conflict declaration changes speed
			d) The aircraft for the conflict declaration changes level
		*/
		virtual void SetConflictDeclarationScoreEnabled(bool a_enabled) = 0;

		virtual void SetConflictDeclarationAudioEnabled(bool a_enabled) = 0;

		virtual void SetConflictDeclarationSpeedChange(bool a_enabled) = 0;

		virtual void SetConflictDeclarationLevelChange(bool a_enabled) = 0;

		/*!
		 * Set the update counter formatter string.
		 * 
		 * Setting this value implies that the counter should be displayed.
		 * The format should contain '%1' which will be the insert position 
		 * for the number of updates.
		 *
		 * \param format 
		 */
		virtual void set_counter_format(const char *format) = 0;

		/*!
		 * Set the horizontal distance of minimum seperation.
		 *
		 * The minimum horizontal distance between two aircraft for the 
		 * for the aircraft not to be in conflict with each other. Both 
		 * a vertical and a horizontal violation would need to occur for
		 * an actual conflict situation.
		 *
		 * A value for the horizontal DOMS should always be set.
		 *
		 * \param dom
		 *
		 * \sa set_vdoms()
		 */
		virtual void set_hdoms(int) = 0;

		/*!
		 * Set the vertical distance of minimum seperation.
		 *
		 * The minimum vertical distance between two aircraft for the 
		 * for the aircraft not to be in conflict with each other.
		 *
		 * If no value is set for the vertial DOMS then altitude violations
		 * are not considered when determining conflict situations.
		 *
		 * \param dom
		 *
		 * \sa set_hdoms()
		 */
		virtual void set_vdoms(int) = 0;

		/*!
		 *
		 */
		virtual void set_conflict_colour( QColor, bool ) = 0;

		/*!
		 *
		 */
		virtual void set_cs_colour( ControlState, QColor, bool ) = 0;

		/*!
		 *
		 */
		virtual void set_scale_tool( const ToolParams & ) = 0;
		virtual void set_altitude_tool( const ToolParams & ) = 0;
		virtual void set_airspeed_tool( const ToolParams & ) = 0;

		virtual void set_keyed_tool( int, atc::CanvasItem::TOOL, std::string ) = 0;

		virtual void set_srprobe( int ) = 0;

		virtual void SetGoalDisplayDetails( const std::string& a_label,
											const std::string& a_globalRef,
											const std::string& a_text) = 0;
		
		virtual void SetCorrectDecisionsDisplayDetails(	const std::string& a_label,
														const std::string& a_globalRef,
														const std::string& a_text) = 0;

		virtual void SetIncorrectDecisionsDisplayDetails(	const std::string& a_label,
															const std::string& a_globalRef,
															const std::string& a_text) = 0;

		virtual void add_scoring( Score * ) = 0;

		/*!
		 *
		 */
		virtual void add_info_block( GridPosition ) = 0;
		virtual void add_time_info() = 0;
		virtual void add_goal_info() = 0;
		virtual void AddSelfReferentGoalInfo() = 0;
		virtual void AddNormativeGoalInfo() = 0;
		virtual void AddCorrectDecisionsInfo() = 0;
		virtual void AddIncorrectDecisionsInfo() = 0;
		virtual void add_score_info() = 0;
		virtual void add_tool_info() = 0;

		/*!
		 *
		 */
		virtual void set_scale_positon( GridPosition ) = 0;

		virtual void SetAircraftDeclarationText(	unsigned int a_row, 
													const std::string& a_value) = 0;

		virtual void SetAircraftDeclarationButton(	const std::string& a_name, 
													const std::string& a_type, 
													const std::string& a_label) = 0;

		virtual AircraftDeclaration GetAircraftDeclaration() const = 0;
	};

}

#endif
